#include<muduo/net/TcpClient.h>
#include<muduo/net/TcpConnection.h>
#include<muduo/net/EventLoopThread.h>
#include<muduo/net/EventLoop.h>
#include<muduo/net/Buffer.h>
#include<muduo/net/EventLoopThread.h>
#include<iostream>

// class DictClient
// {
//     public:
//          DictClient(const std::string&sip,int sport):
//              _client(_baseloop,muduo::net::InetAddress(sip,sport),"DictClient"),
//              _downlatch(1),
//              _baseloop(_loopThread.startLoop())
//          {
//               //建立连接的回调
//               _client.setConnectionCallback(std::bind(&DictClient::onConnection,this,std::placeholders::_1));
//               //建立连接消息的回调
//               _client.setMessageCallback(std::bind(&DictClient::onMessage,this,std::placeholders::_1,std::placeholders::_2,
//               std::placeholders::_3));
//               //连接服务器
//               _client.connect();
//               //阻塞等待
//               _downlatch.wait();
//          }

//          void onConnection(const muduo::net::TcpConnectionPtr &conn)
//          {
//              if (conn->connected())
//              {
//                  std::cout << "连接建立成功" << std::endl;
//                  _downlatch.countDown();//计数器减减
//                  _conn = conn;
//              }
//              else
//              {
//                  std::cout << "连接建失败" << std::endl;
//                  _conn.reset();
//              }
//          }

//          void onMessage(const muduo::net::TcpConnectionPtr &conn, muduo::net::Buffer *_buff, muduo::Timestamp stamp)
//          {
//              //获取得到的消息
//              std::string msg = _buff->retrieveAllAsString();
//              // 打印出来
//              std::cout << msg << std::endl;
//          }

//          //事件发送接口
//          bool send(const std::string& msg)
//          {
//              if(_conn->connected() == false)
//              {
//                  std::cout << "连接断开，发送事件失败" << std::endl;
//                  return false;
//              }

//              _conn->send(msg);
//              return true;
//          }

//     private:
//     //接收事件对象
//     muduo::net::TcpConnectionPtr _conn;
//     //异步接口
//     muduo::CountDownLatch _downlatch;
//     //事件循环线程，实例化好后就会创建
//     muduo::net::EventLoopThread _loopThread;
//     //事件循环监听
//     muduo::net::EventLoop* _baseloop;//要找地方开启循环监控。但是是一个死循环，不能在客户端直接开启循环
//     // 客户端
//     muduo::net::TcpClient _client;
// };

// int main()
// {
//    DictClient client("127.0.0.1",9090);
//    std::string msg;
//    while (1)
//    {
//       std::cin>>msg;
//       client.send(msg);
//    }
//     return 0;
// }


#include<muduo/net/TcpClient.h>
#include<muduo/net/EventLoop.h>
#include<muduo/net/EventLoopThread.h>
#include<muduo/net/TcpConnection.h>
#include<iostream>
#include<string>

class DictClient
{
   
   public:
       DictClient(const std::string&sip,int sport)
       :_client(_baseloop,muduo::net::InetAddress(sip,sport),"DictClient"),
       _downtach(1),
       _baseloop(_loop.startLoop())
       {
           //开始设置连接回调
           _client.setConnectionCallback(std::bind(&DictClient::onConnection,this,std::placeholders::_1));
           //设置消息回调
           _client.setMessageCallback(std::bind(&DictClient::onMessage,this,std::placeholders::_1,
           std::placeholders::_2,std::placeholders::_3));
           //开始连接，连接是异步的所以要配合downtach来进行异步等待避免提前send
           _client.connect();
           //downtach等待
           _downtach.wait();
       }

       void onConnection(const muduo::net::TcpConnectionPtr&conn)
       {
            if(!conn->connected())
            {
                std::cout << "连接不成功" << std::endl;
                _conn.reset();
            }
            else
            {
                _conn = conn;
                //downtach计数减一
                _downtach.countDown();
            }
       }

       void onMessage(const muduo::net::TcpConnectionPtr&conn,muduo::net::Buffer*_buff,const muduo::Timestamp& stamp)
       {
             //得到消息
             std::string mess = _buff->retrieveAllAsString();
             //打印消息
             std::cout << mess << std::endl;
       }


       //发送请求函数
       void send(std::string&msg)
       {
           _conn->send(msg);
       }

   private:
       muduo::net::EventLoopThread _loop;//用来进行事件的监听，使用其它线程开启，为了避免无限循环
       muduo::net::EventLoop* _baseloop;
       muduo::net::TcpConnectionPtr _conn;
       muduo::CountDownLatch _downtach;
       muduo::net::TcpClient _client;
};

int main()
{
    DictClient client("127.0.0.1",9090);
    std::string message;
    while(1)
    {
        std::cin >> message;
        client.send(message);
    }

    return 0;
}